package registry

import (
	"log"
	"time"
	"xin-job/client/cbiz"
	"xin-job/client/sconf"
	"xin-job/core/biz"
)

var instance = &ExecutorRegistry{
	client:   cbiz.GetBizClient(),
	stopFlag: make(chan struct{}),
}

func GetInstance() *ExecutorRegistry {
	return instance
}

// ExecutorRegistry 执行器注册器
type ExecutorRegistry struct {
	client   *cbiz.BizClient
	stopFlag chan struct{} // 标记是否停机
}

func (r *ExecutorRegistry) Start(appName, address string) {
	if appName == "" {
		log.Panicln(">>>>>>>>>>> xxl-job, executor registry config fail, appname is null.")
		return
	}

	go func() {
		for {
			registryParam := biz.RegistryParam{
				RegistryGroup: "EXECUTOR",
				RegistryKey:   appName,
				RegistryValue: address,
			}

			select {
			case <-r.stopFlag:
				// 停机，取消注册
				if len(sconf.ServerConf.AdminAddressList) > 0 {
					for _, adminAddressUrl := range sconf.ServerConf.AdminAddressList {
						r.client.AdminAddressUrl = adminAddressUrl

						// 向调度中心发起注册
						registryResult := r.client.RegistryRemove(&registryParam)
						if registryResult.Code == 200 {
							// 向其中一个调度中心注册完成
							log.Printf(">>>>>>>>>>> xxl-job registry-remove success, registryParam:%v, registryResult:%v\n", registryParam, registryResult)
							break
						} else {
							log.Printf(">>>>>>>>>>> xxl-job registry-remove fail, registryParam:%v, registryResult:%v\n", registryParam, registryResult)
						}
					}
				}
			default:
				if len(sconf.ServerConf.AdminAddressList) > 0 {
					for _, adminAddressUrl := range sconf.ServerConf.AdminAddressList {
						r.client.AdminAddressUrl = adminAddressUrl

						// 向调度中心发起注册
						registryResult := r.client.Registry(&registryParam)
						if registryResult.Code == 200 {
							// 向其中一个调度中心注册完成
							log.Printf(">>>>>>>>>>> xxl-job registry success, registryParam:%v, registryResult:%v\n", registryParam, registryResult)
							break
						} else {
							log.Printf(">>>>>>>>>>> xxl-job registry fail, registryParam:%v, registryResult:%v\n", registryParam, registryResult)
						}
					}
				}

				// 睡眠 30 s
				// 维持心跳
				time.Sleep(30 * time.Second)
			}
		}
	}()
}

func (r *ExecutorRegistry) Stop() {
	r.stopFlag <- struct{}{}
}
